﻿import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.sql.*;
// 用户管理
public class UserManagement {
	public static JPanel UserManagement;//用户管理面板
	static JTable UserTable;// 用户表 表格对象
	/// 更新用户列表数据
	public static void UpdateUserData() {	
		try{
			// 更新用户组数据
			Statement stmt = Main.conn.createStatement();// 创建执行SQL的对象
			ResultSet rs2 = stmt.executeQuery("SELECT COUNT(*) FROM `HotelSysteam`.User;");// 执行查询语句，返回表数据
			rs2.next();// 移动指针到第一行
			int i = rs2.getInt(1);// 获取用户数量
			ResultSet rs = stmt.executeQuery("SELECT * FROM `HotelSysteam`.User;");// 执行查询语句，返回表数据
			// 遍历结果集
			// 创建Object[][]
			Object[][] data = new Object[i][2];// 创建对象数组，大小为行数*列数
			while (rs.next()) {// 如果存在该用户
				int Level = Byte.parseByte(rs.getString("Level"));// 获取权限
				String UserName = rs.getString("user");// 获取用户名
				data[rs.getRow() - 1][0] = UserName;// 获取用户名
				switch (Level) {
				case 0:data[rs.getRow() - 1][1] = "无权限";break;
				case 1:data[rs.getRow() - 1][1] = "报表";break;
				case 2:data[rs.getRow() - 1][1] = "客房服务";break;
				case 3:data[rs.getRow() - 1][1] = "前台";break;
				case 4:data[rs.getRow() - 1][1] = "超管";break;
				default:data[rs.getRow() - 1][1] = "未知权限";break;// 你听说过一个测试工程师进入一家酒吧的故事吗？
				}
			}
			rs.close();// 关闭结果集
			rs2.close();// 关闭结果集
			stmt.close();// 关闭执行SQL的对象
			// 创建表格模型
			DefaultTableModel model = new DefaultTableModel(data,new String[]{"用户名","权限"});// 创建表格模型，传入数据和列名
			// 修改表格对象
			UserTable.setModel(model);// 修改表格对象
		}catch(Exception e){// 如果查询失败，则显示错误
			JOptionPane.showMessageDialog(null, "查询用户列表失败，请联系管理员", "错误", JOptionPane.ERROR_MESSAGE);
			e.printStackTrace();
		}
	}
	public static void init() 
	{
		System.out.println("正在初始化用户管理界面");
		UserManagement = new JPanel();//创建一个面板，使用网格布局
		GridBagLayout grid1 = new GridBagLayout();
		// 添加到面板
		UserManagement.setLayout(grid1);
		// 创建用户名和密码输入框
		JTextField UserName = new JTextField();//用户名
		JPasswordField Password = new JPasswordField();//密码
		// 创建按钮
		JButton Register = new JButton("注册/修改");
		JButton Delete = new JButton("删除用户");
		// 创建单选框
		JRadioButton Admin = new JRadioButton("管理");
		JRadioButton FrontDesk = new JRadioButton("前台");
		JRadioButton Report = new JRadioButton("报表");
		JRadioButton serButton = new JRadioButton("服务");
		// 文本框宽度150
		UserName.setPreferredSize(new Dimension(200, 30));
		Password.setPreferredSize(new Dimension(200, 30));
		// 按钮宽度设置
		Register.setPreferredSize(new Dimension(120, 30));
		Delete.setPreferredSize(new Dimension(120, 30));
		// 添加到面板
		GridBagConstraints g1 = new GridBagConstraints();
		g1.gridx = 0;
		g1.gridy = 0;
		UserManagement.add(new JLabel("用户名:"), g1);
		g1 = new GridBagConstraints();
		g1.gridx = 0;
		g1.gridy = 1;
		UserManagement.add(new JLabel("密码:"), g1);
		g1 = new GridBagConstraints();
		g1.gridx = 1;
		g1.gridy = 0;
		g1.gridwidth = 3;// 文本框的宽度占用3个单位
		UserManagement.add(UserName, g1);
		g1 = new GridBagConstraints();
		g1.gridx = 1;
		g1.gridy = 1;
		g1.gridwidth = 3;
		UserManagement.add(Password, g1);
		// 添加注册/修改按钮
		g1 = new GridBagConstraints();
		g1.gridx = 0;
		g1.gridy = 2;
		g1.gridwidth = 2;
		UserManagement.add(Register, g1);
		// 添加删除用户按钮
		g1 = new GridBagConstraints();
		g1.gridx = 2;
		g1.gridy = 2;
		g1.gridwidth = 2;
		UserManagement.add(Delete, g1);
		// 添加四个单选框，用于表示用户权限
		ButtonGroup group = new ButtonGroup();
		group.add(Admin);
		group.add(FrontDesk);
		group.add(Report);
		group.add(serButton);
		g1 = new GridBagConstraints();
		g1.gridx = 0;
		g1.gridy = 3;
		g1.gridwidth = 2;
		UserManagement.add(Admin, g1);
		g1 = new GridBagConstraints();
		g1.gridx = 2;
		g1.gridy = 3;
		g1.gridwidth = 2;
		UserManagement.add(FrontDesk, g1);
		g1 = new GridBagConstraints();
		g1.gridx = 0;
		g1.gridy = 4;
		g1.gridwidth = 2;
		UserManagement.add(Report, g1);
		g1 = new GridBagConstraints();
		g1.gridx = 2;
		g1.gridy = 4;
		g1.gridwidth = 2;
		UserManagement.add(serButton, g1);
		// 创建用户列表
		UserTable = new JTable();
		// 两列头，第一列是用户名，第二列是权限
		String[] head = { "用户名", "权限" };
		UserTable.setModel(new DefaultTableModel(null, head));
		// 设置列宽
		UserTable.getColumnModel().getColumn(0).setPreferredWidth(120);
		UserTable.getColumnModel().getColumn(1).setPreferredWidth(20);
		// 添加到面板
		g1 = new GridBagConstraints();
		g1.gridx = 0;
		g1.gridy = 5;
		g1.gridwidth = 4;// 占用4个单位
		JScrollPane UserTableScroll = new JScrollPane(UserTable);// 添加到面板
		// 设置宽度
		UserTableScroll.setPreferredSize(new Dimension(240, 400));
		// 添加到面板
		UserManagement.add(UserTableScroll, g1);
		// 添加到面板
		g1 = new GridBagConstraints();
		g1.gridx = 0;
		g1.gridy = 5;
		g1.gridwidth = 4;// 占用4个单位
		// 布局完毕 设置回调函数，当点击按钮时执行以下代码
		//////////////////////////////////////////////////////////////////////////////////////////////////////
		// 注册/修改按钮
		//////////////////////////////////////////////////////////////////////////////////////////////////////
		Register.addActionListener(e -> {
			// 获取用户名和密码
			String oUserName = UserName.getText();
			char[] oPassword = Password.getPassword();
			// 用户名为空则提示并返回
			if (oUserName.equals("")) {
				JOptionPane.showMessageDialog(Main.window, "用户名不能为空", "提示", JOptionPane.ERROR_MESSAGE);
				return;
			}
			// 如果用户名为root则提示并返回
			if (oUserName.equals("root")) {
				JOptionPane.showMessageDialog(Main.window, "root用户是系统管理员\n不能修改，也不允许修改\n如果需要修改请使用SQL指令去数据库中修改", "提示", JOptionPane.ERROR_MESSAGE);
				return;
			}
			// 获取单选框的权限
			int Permission = 0;
			if (Admin.isSelected()) {
				Permission = 4;// 管理
			} else if (FrontDesk.isSelected()) {
				Permission = 3;// 前台
			} else if (Report.isSelected()) {
				Permission = 1;// 报表
			} else if (serButton.isSelected()) {
				Permission = 2;// 服务
			}
			// 调用数据库，注册/修改用户
			UpdateUserData();// 更新本地用户表
			// 此时UserTable已经更新，对比是否重名，如果是则提示是否修改，没有重名则直接添加
			// 循环遍历
			for (int i = 0; i < UserTable.getRowCount(); i++) {
				if (oUserName.equals(UserTable.getValueAt(i, 0))) {// 如果用户名相同，则提示是否修改
					if (JOptionPane.showConfirmDialog(Main.window, "该用户已存在，是否修改？", "提示", JOptionPane.YES_NO_OPTION) == 0) {// 如果点击了是
						// 检查密码是否为空，如果为空则不修改密码
						if (oPassword.length != 0) {
							// 发起sql语句修改密码
							// SET PASSWORD FOR '用户名'@'%' = PASSWORD('密码');
							// 执行sql语句
							try {
								Statement st = Main.conn.createStatement();
								st.executeUpdate("SET PASSWORD FOR '" + oUserName + "'@'%' = PASSWORD('" + new String(oPassword) + "');");// 执行sql语句
								st.executeUpdate("flush privileges;");// 刷新权限
								JOptionPane.showMessageDialog(Main.window, "修改密码成功", "提示", JOptionPane.INFORMATION_MESSAGE);
								st.close();// 关闭语句对象
							} catch (SQLException e1) {
								// 错误提示
								JOptionPane.showMessageDialog(Main.window, "修改密码失败", "提示", JOptionPane.ERROR_MESSAGE);
								e1.printStackTrace();
							}// 创建语句对象
						} 
						// 修改权限 分两步，第一步先修改显示上的权限，然后再修改数据库中的权限
						// 使用UPDATE HotelSysteam.User SET User.Level = '权限' WHERE User.`User`='用户名';更改显示权限
						if (Permission != 0){// 如果有选中权限
							try {
								Statement st = Main.conn.createStatement();
								// 修改数据库中的权限
								st.executeUpdate("UPDATE HotelSysteam.User SET User.Level = '" + Permission + "' WHERE User.`User`='" + oUserName + "';");// 执行sql语句
								st.executeUpdate("REVOKE ALL ON * . * FROM '" + oUserName + "'@'%';");// 移除其他权限
								st.executeUpdate("REVOKE ALL ON `HotelSysteam`.* FROM '" + oUserName + "'@'%';");// 移除其他权限
								switch (Permission) {
								// 修改权限4为管理员,授予全局权限
								case 4:st.executeUpdate("GRANT ALL PRIVILEGES ON * . * TO '" + oUserName + "'@'%' WITH GRANT OPTION;");break;
								// 修改权限3为前台人员，授予HotelSysteam数据库下全部权限并尝试移除其他权限
								case 3:st.executeUpdate("GRANT ALL ON `HotelSysteam`.* TO '" + oUserName + "'@'%' WITH GRANT OPTION;");break;
								case 2:// 修改权限2为服务员，和报表的权限等级相同
								case 1:// 修改权限1为报表人员，授予HotelSysteam数据库下只读权限并尝试移除其他权限
									st.executeUpdate("GRANT SELECT ON HotelSysteam.* TO '" + oUserName + "'@'%';");// 授权
									break;
								}
								st.close();// 关闭语句对象
								JOptionPane.showMessageDialog(Main.window, "修改权限成功", "提示", JOptionPane.INFORMATION_MESSAGE);
							} catch (SQLException e1) {// 错误提示
								JOptionPane.showMessageDialog(Main.window, "修改权限失败", "提示", JOptionPane.ERROR_MESSAGE);
								e1.printStackTrace();
							}
							// 完成后将复选框复选框选中状态改为false
							Admin.setSelected(false);
							FrontDesk.setSelected(false);
							Report.setSelected(false);
							serButton.setSelected(false);
							// 刷新数据表
							UpdateUserData();// 更新本地用户表
						}
						return;// 密码和权限完成修改
					} else {// 如果点击了否，则不修改
						return;
					}
				}
			}
			// 没有重名，执行注册程序
			System.out.println("注册用户："+oUserName);
			// 检查是否密码为空，如果为空则发出提示
			if (oPassword.length == 0) {
				JOptionPane.showMessageDialog(Main.window, "密码不能为空", "提示", JOptionPane.ERROR_MESSAGE);
				return;
			}
			// 检查权限是否为空，如果为空则发出提示
			if (Permission == 0) {
				JOptionPane.showMessageDialog(Main.window, "请选择权限", "提示", JOptionPane.ERROR_MESSAGE);
				return;
			}
			// 发起sql语句注册用户
			// CREATE USER '用户名'@'%' IDENTIFIED BY '密码';
			try {
				Statement st = Main.conn.createStatement();
				// 执行sql语句
				st.executeUpdate("CREATE USER '" + oUserName + "'@'%' IDENTIFIED BY '" + new String(oPassword) + "';");// 执行sql语句
			// 授予权限(由于新用户本来就没权限所以不需要删除旧权限)
				switch(Permission) {
					case 4:st.executeUpdate("GRANT ALL PRIVILEGES ON * . * TO '" + oUserName + "'@'%' WITH GRANT OPTION;");break;
					case 3:st.executeUpdate("GRANT ALL ON `HotelSysteam`.* TO '" + oUserName + "'@'%' WITH GRANT OPTION;");break;
					case 2:
					case 1:
						st.executeUpdate("GRANT SELECT ON HotelSysteam.* TO '" + oUserName + "'@'%';");// 授权
					break;
				}
				// 修改显示权限
				st.executeUpdate("INSERT INTO `HotelSysteam`.`User` (`User`, `Level`) VALUES ('"+ oUserName +"', "+Permission+");");
				// 刷新权限
				st.executeUpdate("flush privileges;");
				// 刷新数据表
				UpdateUserData();// 更新本地用户表
				JOptionPane.showMessageDialog(Main.window, "注册成功", "提示", JOptionPane.INFORMATION_MESSAGE);
				st.close();// 关闭语句对象
				// 完成后将复选框选中状态改为false
				Admin.setSelected(false);
				serButton.setSelected(false);
				FrontDesk.setSelected(false);
				Report.setSelected(false);
			} catch (SQLException e1) {
				// 发生异常
				JOptionPane.showMessageDialog(Main.window, "注册用户失败，因为被阻止或连接中断", "提示", JOptionPane.ERROR_MESSAGE);
				e1.printStackTrace();
			}
		});
		//////////////////////////////////////////////////////////////////////////////////////////
		// 删除用户按钮
		//////////////////////////////////////////////////////////////////////////////////////////
		Delete.addActionListener(e -> {
			// 获取选中的用户名
			String oUserName = UserName.getText();
			// 判断是否为空
		if (oUserName.length() == 0) {
				JOptionPane.showMessageDialog(Main.window, "请选择用户", "提示", JOptionPane.ERROR_MESSAGE);
				return;
			}
			// 如果用户名为root则拒绝删除
			if (oUserName.equals("root")) {
				JOptionPane.showMessageDialog(Main.window, "无法删除root用户，该用户为系统核心用户", "提示", JOptionPane.ERROR_MESSAGE);
				return;
			}
			// 弹窗向用户二次确认
			int result = JOptionPane.showConfirmDialog(Main.window, "确定要删除用户" + oUserName + "吗?", "提示", JOptionPane.YES_NO_OPTION);
			if (result == 0) {// 如果点击了是
				try {
					Statement st = Main.conn.createStatement();// 创建语句对象
					st.executeUpdate("DROP USER '" + oUserName + "'@'%';");// 删除用户
					st.executeUpdate("DELETE FROM `HotelSysteam`.`User` WHERE User = '" + oUserName + "';");// 删除显示权限
					st.close();// 关闭语句对象
					JOptionPane.showMessageDialog(Main.window, "删除用户成功", "提示", JOptionPane.INFORMATION_MESSAGE);
					// 刷新数据表
					UpdateUserData();// 更新本地用户表
				} catch (SQLException e1) {// 错误提示
					JOptionPane.showMessageDialog(Main.window, "删除用户失败\n也许对方还在线\n或该账户存在异常", "提示", JOptionPane.ERROR_MESSAGE);
					e1.printStackTrace();
				}
			} else {// 如果点击了否，则不删除
				return;
			}
		});
	}	
}
